package com.example.smartg.ui.notifications;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import com.example.smartg.Login;
import com.example.smartg.R;
import com.example.smartg.SmartGMainActivity;
import com.example.smartg.utils.ToastUtil;
import com.zkteco.android.biometric.core.device.ParameterHelper;
import com.zkteco.android.biometric.core.device.TransportType;
import com.zkteco.android.biometric.core.utils.LogHelper;
import com.zkteco.android.biometric.core.utils.ToolUtils;
import com.zkteco.android.biometric.module.fingerprintreader.FingerprintCaptureListener;
import com.zkteco.android.biometric.module.fingerprintreader.FingerprintSensor;
import com.zkteco.android.biometric.module.fingerprintreader.FingprintFactory;
import com.zkteco.android.biometric.module.fingerprintreader.ZKFingerService;
import com.zkteco.android.biometric.module.fingerprintreader.exception.FingerprintException;

import java.util.HashMap;
import java.util.Map;

public class NotificationsFragment extends Fragment {

    private static final int VID = 6997;
    private static final int PID = 288;
    private ImageView imageView = null;
    private boolean bstart = false;
    private boolean isRegister = false;
    private int uid = 1;
    private byte[][] regtemparray = new byte[3][2048];  //register template buffer array
    private int enrollidx = 0;
    private byte[] lastRegTemp = new byte[2048];
    String result = "";


    public View view;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (view == null) {
            view = inflater.inflate(R.layout.fragment_notifications, container, false);
        }
        ImageView imageView0 = (ImageView) view.findViewById(R.id.return_to_home);
        imageView0.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), SmartGMainActivity.class);
                startActivity(intent);
            }
        });
        imageView = (ImageView) view.findViewById(R.id.finger_print) ;
        startFingerprintSensor();
        initUSBPermission();
        try {
            OnBnBegin();
        } catch (FingerprintException e) {
            e.printStackTrace();
        }
        OnBnEnroll();
        return view;
    }

    private FingerprintSensor fingerprintSensor = null;

    private final String ACTION_USB_PERMISSION = "com.example.smartg.USB_PERMISSION";

    private void initUSBPermission() {
        UsbManager usbManager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE);
        for (UsbDevice device : usbManager.getDeviceList().values()) {
            if (device.getVendorId() == VID && device.getProductId() == PID) {
                Intent intent = new Intent(ACTION_USB_PERMISSION);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
                usbManager.requestPermission(device, pendingIntent);
            }
        }
    }

    private void startFingerprintSensor() {
        // Define output log level
        LogHelper.setLevel(Log.ASSERT);
        LogHelper.setNDKLogLevel(Log.ASSERT);
        // Start fingerprint sensor
        Map fingerprintParams = new HashMap();
        //set vid
        fingerprintParams.put(ParameterHelper.PARAM_KEY_VID, VID);
        //set pid
        fingerprintParams.put(ParameterHelper.PARAM_KEY_PID, PID);
        fingerprintSensor = FingprintFactory.createFingerprintSensor(getActivity(), TransportType.USB, fingerprintParams);
    }

    public void OnBnBegin() throws FingerprintException {
        try {
            if (bstart) return;
            fingerprintSensor.open(0);
            final FingerprintCaptureListener listener = new FingerprintCaptureListener() {
                @Override
                public void captureOK(final byte[] fpImage) {
                    final int width = fingerprintSensor.getImageWidth();
                    final int height = fingerprintSensor.getImageHeight();
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (null != fpImage) {
                                ToolUtils.outputHexString(fpImage);
                                LogHelper.i("width=" + width + "\nHeight=" + height);
                                Bitmap bitmapFp = ToolUtils.renderCroppedGreyScaleBitmap(fpImage, width, height);
                                //saveBitmap(bitmapFp);
                                imageView.setImageBitmap(bitmapFp);
                            }
                            //Log.e("error","FakeStatus:" + fingerprintSensor.getFakeStatus());
                        }
                    });
                }

                @Override
                public void captureError(FingerprintException e) {
                    final FingerprintException exp = e;
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            LogHelper.d("captureError  errno=" + exp.getErrorCode() +
                                    ",Internal error code: " + exp.getInternalErrorCode() + ",message=" + exp.getMessage());
                        }
                    });
                }

                @Override
                public void extractError(final int err) {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.e("error","extract fail, errorcode:" + err);
                        }
                    });
                }

                @Override
                public void extractOK(final byte[] fpTemplate) {
                    final byte[] tmpBuffer = fpTemplate;
                    final int templateLen = fingerprintSensor.getLastTempLen();
                    Log.e("extractOK", Integer.toString(templateLen));
                    //Base64 Template
                    //String strBase64 = Base64.encodeToString(tmpBuffer, 0, templateLen, Base64.NO_WRAP);
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (isRegister) {
                                byte[] bufids = new byte[256];
                                int ret = ZKFingerService.identify(tmpBuffer, bufids, 55, 1);
                                if (ret > 0) {
                                    String strRes[] = new String(bufids).split("\t");
                                    Log.e("error","the finger already enroll by " + strRes[0] + ",cancel enroll");
                                    isRegister = false;
                                    enrollidx = 0;
                                    return;
                                }

                                if (enrollidx > 0 && ZKFingerService.verify(regtemparray[enrollidx - 1], tmpBuffer) <= 0) {
                                    Log.e("error","please press the same finger 3 times for the enrollment");
                                    return;
                                }
                                System.arraycopy(tmpBuffer, 0, regtemparray[enrollidx], 0, 2048);
                                enrollidx++;
                                if (enrollidx == 3) {
                                    byte[] regTemp = new byte[2048];
                                    if (0 < (ret = ZKFingerService.merge(regtemparray[0], regtemparray[1], regtemparray[2], regTemp))) {
                                        ZKFingerService.save(regTemp, "郑楚鑫");
                                        System.arraycopy(regTemp, 0, lastRegTemp, 0, ret);
                                        //Base64 Template
                                        String strBase64 = Base64.encodeToString(regTemp, 0, ret, Base64.NO_WRAP);
                                        result = strBase64;
                                        Log.e("error","enroll succ, uid:" + uid + "count:" + ZKFingerService.count());
                                    } else {
                                        Log.e("error","enroll fail");
                                    }
                                    isRegister = false;
                                } else {
                                    Log.e("error","You need to press the " + (3 - enrollidx) + "time fingerprint");
                                }
                            } else {

//                                 测试
                                ZKFingerService.clear();
                                Log.e("count", Integer.toString(ZKFingerService.count()));
                                Log.e("长度", result);
                                byte[] regTemp = Base64.decode(result, Base64.NO_WRAP);
                                Log.e("le", Integer.toString(regTemp.length));
                                ZKFingerService.save(regTemp, "郑楚鑫");
                                Log.e("count2", Integer.toString(ZKFingerService.count()));
//                                old
                                byte[] bufids = new byte[256];
                                int ret = ZKFingerService.identify(tmpBuffer, bufids, 70, 1);
                                if (ret > 0) {
                                    String strRes[] = new String(bufids).split("\t");
                                    Log.e("error","identify succ, userid:" + strRes[0] + ", score:" + strRes[1]);
                                } else {
                                    Log.e("error","identify fail");
                                }
                            }
                        }
                    });
                }


            };
            fingerprintSensor.setFingerprintCaptureListener(0, listener);
            fingerprintSensor.startCapture(0);
            bstart = true;
            Log.e("open", "start capture succ");
        } catch (FingerprintException e) {
            Log.e("error","begin capture fail.errorcode:" + e.getErrorCode() + "err message:" + e.getMessage() + "inner code:" + e.getInternalErrorCode());
        }
    }

    public void OnBnStop() throws FingerprintException {
        try {
            if (bstart) {
                //stop capture
                fingerprintSensor.stopCapture(0);
                bstart = false;
                fingerprintSensor.close(0);
                Log.e("error","stop capture succ");
                ToastUtil.success(getActivity(), "成功断开指纹识别器！");
//                Log.e("info:","stop capture succ");
            } else {
                Log.e("error","already stop");
                ToastUtil.success(getActivity(), "指纹识别器已经断开！");
//                System.out.print("already stop");
//                Log.e("info:","already stop");
            }
        } catch (FingerprintException e) {
            Log.e("error","stop fail, errno=" + e.getErrorCode() + "\nmessage=" + e.getMessage());
//            Log.e("info:","stop fail, errno=" + e.getErrorCode() + "\nmessage=" + e.getMessage());
        }

    }

    public void OnBnEnroll() {
        if (bstart) {
            isRegister = true;
            enrollidx = 0;
            Log.e("error","You need to press the 3 time fingerprint");
        } else {
            Log.e("error","please begin capture first");
        }
    }

    public void OnBnVerify() {
        if (bstart) {
            isRegister = false;
            enrollidx = 0;
        } else {
            Log.e("error","please begin capture first");
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }
    
}